<template>
    <div class="upload-file flex flex-row" style="gap:20px">
        <li class="el-upload--picture-card" v-for="(item, index) in cropFileList" :key="index" v-if="!showUploader">
            <el-image style="width: 100%; height: 100%" :src="item.url" fit="cover"></el-image>
        </li>
        <el-upload :http-request="uploadFn" action list-type="picture-card" :auto-upload="true" :file-list="cropFileList"
            :show-file-list="showUploader" name="upload" drag :limit="limit" :on-success="onUploadChange"
            :on-exceed="onUploadExceed" multiple v-bind="$attrs" :on-remove="onRemoveChange"
            :on-preview="handleUploadedPreview">
            <i slot="default" class="el-icon-plus"></i>
        </el-upload>
    </div>
</template>
  
<script>
import draggable from "vuedraggable";
import { getOssData, sendOssData } from '@/api/common';
function convertBase64UrlToBlob(urlData) {
    var arr = urlData.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
};
function photoCompress(file, w, objDiv) {
    var ready = new FileReader();
    /* 开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容. */
    ready.readAsDataURL(file);
    ready.onload = function () {
        var re = this.result;
        canvasDataURL(re, w, objDiv);
    };
};
function canvasDataURL(path, obj, callback) {
    var img = new Image();
    img.src = path;
    img.onload = function () {
        var that = this;
        // 默认按比例压缩
        var maxWidth = 750,
            maxHeight = 750;

        var w = that.width,
            h = that.height,
            scale = w / h,
            targetWidth = w,
            targetHeight = h;
        // 图片尺寸超过750x750的限制
        if (w > maxWidth || h > maxHeight) {
            if (w / h > maxWidth / maxHeight) {
                // 更宽，按照宽度限定尺寸
                targetWidth = maxWidth;
                targetHeight = Math.round(maxWidth * (h / w));
            } else {
                targetHeight = maxHeight;
                targetWidth = Math.round(maxHeight * (w / h));
            }
        }
        w = obj.width || targetWidth;
        h = obj.height || targetWidth / scale;
        var quality = 1; // 默认图片质量为0.7
        // 生成canvas
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        // 创建属性节点
        // var anw = document.createAttribute("width");
        // anw.nodeValue = w;
        // var anh = document.createAttribute("height");
        // anh.nodeValue = h;
        // canvas.setAttributeNode(anw);
        // canvas.setAttributeNode(anh);
        // ctx.drawImage(that, 0, 0, w, h);
        canvas.width = targetWidth;
        canvas.height = targetHeight;
        ctx.fillStyle = "#fff";
        ctx.fillRect(0, 0, targetWidth, targetHeight);

        ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
        // ctx.fillStyle = "#fff";
        // // 清除画布
        // ctx.clearRect(0, 0, targetWidth, targetHeight);
        // // 图片压缩
        // ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
        // 图像质量
        if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
            quality = obj.quality;
        }
        // quality值越小，所绘制出的图像越模糊
        var base64 = canvas.toDataURL("image/jpeg", quality);
        // 回调函数返回base64的值
        callback(base64);
    };
}
export default {
    components: { draggable },
    model: {
        event: 'change', // 这个事件与下面的emit事件与之对应
        prop: 'value' // 
    },
    props: {
        showUploader: {
            type: Boolean,
            default: true
        },
        // 上传文件数量限制
        limit: {
            type: Number,
            default: 5
        },
        // 单个上传文件大小限制
        fileSize: {
            type: Number,
            default: 50000
        },
        // 允许上传的文件类型, 例如['png', 'jpg', 'jpeg']
        fileType: {
            type: Array,
            default: () => ["doc", "xls", "ppt", "txt", "pdf", 'png', 'jpg', 'jpeg']
        },
        value: {
            type: String,
        },
        _compress: {
            type: Boolean,
            default: false
        },
        _quality: {
            type: Number,
            default: 0.8
        }
    },
    mounted() {
        const unwatch = this.$watch('value', newVal => {
            if (!newVal) {
                return
            }
            this.updateModelValue(newVal)
            unwatch();
        });
    },
    data() {
        return {
            fileList: [],
            quality: this._quality,
            compress: this._compress
        };
    },
    computed: {
        cropFileList() {
            return this.fileList.map(item => {
                return {
                    name: item.name,
                    url: this.pictureHandle(item.url, 'pc_zoom_small'),
                }
            })
        }
    },
    methods: {
        updateModelValue(val) {
            this.fileList = val.split(',').map(item => {
                return {
                    name: item,
                    url: item,
                }
            });
        },
        async handleUpload(file, cb) {
            let fileObj = file.file ? file.file : file;
            // 生成文件名，作为 key 使用
            const generateFileName = (ossData, file) => {
                const suffix = file.name.slice(file.name.lastIndexOf('.'));
                const filename = Date.now() + suffix;
                return ossData.dir + filename;
            }
            const ossData = await getOssData()
            const key = generateFileName(ossData, fileObj)
            const formdata = new FormData()
            // 注意参数的顺序，key 必须是第一位，表示OSS存储文件的路径
            formdata.append('key', key)
            formdata.append('OSSAccessKeyId', ossData.accessId)
            formdata.append('policy', ossData.policy)
            formdata.append('signature', ossData.signature)
            // 文件上传成功默认返回 204 状态码，可根据需要修改为 200
            formdata.append('success_action_status', '200')
            // file 必须放在最后一位
            formdata.append('file', fileObj, fileObj.name)
            const res = await sendOssData(ossData.host, formdata);
            if (res.status === 200) {
                cb(ossData.host + '/' + key)
            }
        },
        uploadFn(params) {
            let cmd = this.compress ? 'compressFile' : 'handleUpload';
            this[cmd](params, (res) => {
                this.fileList.push({
                    name: res,
                    url: res,
                })
                this.$emit('change', this.fileList.map(item => item.url).join(','))
            })
        },
        // 文件上传添加
        onUploadChange(res) {
            this.pic = res.path
        },
        // 超出文件
        onUploadExceed() {
            this.$message({
                message: '超出上传数量',
                type: 'error',
            })
        },
        // 文件移除
        onRemoveChange(file) {
            let index = this.fileList.findIndex(item => item.url == file.url)
            this.fileList.splice(index, 1)
            this.$emit('change', this.fileList.map(item => item.url).join(','))
        },
        handleUploadedPreview(e) {
            let index = this.cropFileList.findIndex(item => item.url == e.url)
            let list = this.cropFileList.map(item => item.url)
            this.$openPreview(list, index)
        },
        // 压缩上传
        compressFile(fileObj, cb, progressFunction) {
            let file = fileObj.file;
            let size = file.size / 1024;
            let quality = 1;
            if (size > 200 && size < 512) {
                // 200-512k 90%
                quality = 0.9;
            } else if (size >= 512 && size < 1024) {
                // 0.5M-1M 70%
                quality = 0.7;
            } else if (size >= 1024 && size < 2048) {
                // 1M-2M 50%
                quality = 0.5;
            } else if (size >= 2048 && size < 5120) {
                // 2M-5M 30%
                quality = 0.3;
            } else if (size >= 5120 && size < 10240) {
                // 5M-10M 10%
                quality = 0.1;
            } else if (size >= 10240) {
                // 10M以上  5%
                quality = 0.05;
            }
            if (this.quality) {
                quality = this.quality
            }
            console.log('[  quality] >', quality)
            // if (size > 200) { //大于200k，进行压缩上传
            photoCompress(
                file,
                {
                    quality: 1
                },
                base64Codes => {
                    var bl = convertBase64UrlToBlob(base64Codes);
                    bl.name = file.name;
                    bl.uid = file.uid;
                    bl.webkitRelativePath = file.webkitRelativePath;
                    this.handleUpload(bl, cb, progressFunction, true);
                }
            );
            // } else { //小于等于1M 原图上传
            //     this.handleUpload(fileObj, cb, progressFunction, true)
            // }
        },
    }
};
</script>
  